import tkinter as tk
from tkinter import ttk, filedialog, messagebox, scrolledtext
import socket
import threading
import os
import base64
import time
import io
import json
import platform
import subprocess
from datetime import datetime
import random

# 尝试导入可选模块
try:
    from PIL import Image, ImageTk, ImageDraw
    PIL_AVAILABLE = True
except ImportError:
    PIL_AVAILABLE = False

try:
    import psutil
    PSUTIL_AVAILABLE = True
except ImportError:
    PSUTIL_AVAILABLE = False

try:
    import requests
    REQUESTS_AVAILABLE = True
except ImportError:
    REQUESTS_AVAILABLE = False

class StarrySkyChat:
    def __init__(self, root):
        self.root = root
        self.root.title("星穹通信 v2.0 - 跨时空加密频道")
        self.root.geometry("1200x800")
        self.root.configure(bg='#0a0a1a')
        
        # 数据文件路径
        self.data_dir = os.path.join(os.path.expanduser("~"), ".starry_chat")
        self.friends_file = os.path.join(self.data_dir, "friends.json")
        self.settings_file = os.path.join(self.data_dir, "settings.json")
        self.chat_history_dir = os.path.join(self.data_dir, "chat_history")
        
        # 创建数据目录
        os.makedirs(self.data_dir, exist_ok=True)
        os.makedirs(self.chat_history_dir, exist_ok=True)
        
        # 加载数据
        self.friends = self.load_friends()
        self.settings = self.load_settings()
        
        # 设置星空苍穹风格
        self.setup_styles()
        
        # 通信变量
        self.host = self.get_local_ip()
        self.port = self.settings.get('port', 12345)
        self.public_ip = self.get_public_ip()
        self.connected = False
        self.client_socket = None
        self.server_socket = None
        self.current_friend = None
        self.connection_type = None
        
        self.setup_ui()
        self.start_server()
        
    def get_local_ip(self):
        """获取本地IP地址"""
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            s.connect(("8.8.8.8", 80))
            ip = s.getsockname()[0]
            s.close()
            return ip
        except:
            return "127.0.0.1"
    
    def get_public_ip(self):
        """获取公网IP地址"""
        if not REQUESTS_AVAILABLE:
            return "需要requests模块"
        
        try:
            response = requests.get('https://api.ipify.org', timeout=5)
            return response.text
        except:
            return "无法获取公网IP"
    
    def setup_styles(self):
        """设置星空苍穹风格"""
        self.colors = {
            'bg_dark': '#0a0a1a',
            'bg_medium': '#1a1a3a', 
            'bg_light': '#2a2a5a',
            'accent_blue': '#4fc3f7',
            'accent_purple': '#9575cd',
            'accent_green': '#64ffda',
            'accent_yellow': '#ffd54f',
            'accent_red': '#ff6e6e',
            'text_primary': '#e0f7fa',
            'text_secondary': '#b2ebf2'
        }
    
    def setup_ui(self):
        # 主容器
        main_container = tk.Frame(self.root, bg=self.colors['bg_dark'])
        main_container.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 顶部标题栏
        title_frame = tk.Frame(main_container, bg=self.colors['bg_medium'])
        title_frame.pack(fill=tk.X, pady=(0, 10))
        
        title_label = tk.Label(title_frame, text="✦ 星穹通信 v2.0 ✦", 
                              bg=self.colors['bg_medium'], fg=self.colors['accent_blue'],
                              font=('微软雅黑', 20, 'bold'), pady=15)
        title_label.pack()
        
        subtitle_label = tk.Label(title_frame, text="跨时空加密通信系统", 
                                 bg=self.colors['bg_medium'], fg=self.colors['text_secondary'],
                                 font=('微软雅黑', 11))
        subtitle_label.pack()
        
        # 主内容区域
        content_frame = tk.Frame(main_container, bg=self.colors['bg_dark'])
        content_frame.pack(fill=tk.BOTH, expand=True)
        
        # 左侧边栏
        sidebar = tk.Frame(content_frame, bg=self.colors['bg_medium'])
        sidebar.pack(side=tk.LEFT, fill=tk.Y, padx=(0, 10))
        sidebar.pack_propagate(False)
        sidebar.configure(width=300)
        
        # 连接面板
        connection_frame = tk.Frame(sidebar, bg=self.colors['bg_medium'])
        connection_frame.pack(fill=tk.X, padx=15, pady=15)
        
        # 目标地址输入
        target_label = tk.Label(connection_frame, text="目标星际坐标:", 
                               bg=self.colors['bg_medium'], fg=self.colors['text_primary'],
                               font=('微软雅黑', 10))
        target_label.pack(anchor='w', pady=(0, 5))
        
        self.target_entry = tk.Entry(connection_frame, bg=self.colors['bg_light'],
                                    fg=self.colors['text_primary'], 
                                    insertbackground=self.colors['accent_blue'],
                                    relief='flat', bd=1, 
                                    highlightbackground=self.colors['accent_blue'],
                                    highlightthickness=1, 
                                    font=('Consolas', 11))
        self.target_entry.pack(fill=tk.X, pady=(0, 10))
        
        # 端口和按钮行
        port_button_frame = tk.Frame(connection_frame, bg=self.colors['bg_medium'])
        port_button_frame.pack(fill=tk.X)
        
        # 端口设置
        port_label = tk.Label(port_button_frame, text="频率:", 
                             bg=self.colors['bg_medium'], fg=self.colors['text_primary'],
                             font=('微软雅黑', 10))
        port_label.pack(side=tk.LEFT)
        
        self.port_entry = tk.Entry(port_button_frame, bg=self.colors['bg_light'],
                                  fg=self.colors['text_primary'], 
                                  insertbackground=self.colors['accent_blue'],
                                  relief='flat', bd=1, 
                                  highlightbackground=self.colors['accent_blue'],
                                  highlightthickness=1, width=8,
                                  font=('Consolas', 11))
        self.port_entry.insert(0, str(self.port))
        self.port_entry.pack(side=tk.LEFT, padx=(5, 15))
        
        # 连接按钮
        self.connect_btn = tk.Button(port_button_frame, text="开启星门", 
                                    bg=self.colors['accent_blue'], fg='#ffffff',
                                    font=('微软雅黑', 10, 'bold'),
                                    relief='flat', bd=0, cursor='hand2',
                                    command=self.connect_to_target)
        self.connect_btn.pack(side=tk.LEFT, padx=(0, 5))
        
        self.disconnect_btn = tk.Button(port_button_frame, text="关闭星门", 
                                       bg=self.colors['bg_light'], fg=self.colors['text_primary'],
                                       font=('微软雅黑', 10),
                                       relief='flat', bd=0, cursor='hand2',
                                       command=self.disconnect, state=tk.DISABLED)
        self.disconnect_btn.pack(side=tk.LEFT)
        
        # 状态显示
        status_frame = tk.Frame(connection_frame, bg=self.colors['bg_light'])
        status_frame.pack(fill=tk.X, pady=(10, 0))
        
        self.status_label = tk.Label(status_frame, text="🔴 星门关闭 - 等待连接", 
                                    bg=self.colors['bg_light'], fg=self.colors['text_primary'],
                                    font=('微软雅黑', 9), pady=8)
        self.status_label.pack()
        
        # 好友列表
        friends_frame = tk.Frame(sidebar, bg=self.colors['bg_medium'])
        friends_frame.pack(fill=tk.BOTH, expand=True, padx=15, pady=15)
        
        friends_header = tk.Frame(friends_frame, bg=self.colors['bg_medium'])
        friends_header.pack(fill=tk.X, pady=(0, 10))
        
        friends_title = tk.Label(friends_header, text="星际通讯录", 
                                bg=self.colors['bg_medium'], fg=self.colors['accent_purple'],
                                font=('微软雅黑', 12, 'bold'))
        friends_title.pack(side=tk.LEFT)
        
        add_friend_btn = tk.Button(friends_header, text="+ 添加", 
                                  bg=self.colors['accent_purple'], fg='#ffffff',
                                  font=('微软雅黑', 9, 'bold'),
                                  relief='flat', bd=0, cursor='hand2',
                                  command=self.show_add_friend_dialog)
        add_friend_btn.pack(side=tk.RIGHT)
        
        # 好友列表容器
        friends_container = tk.Frame(friends_frame, bg=self.colors['bg_medium'])
        friends_container.pack(fill=tk.BOTH, expand=True)
        
        # 使用Treeview作为好友列表
        self.friends_tree = ttk.Treeview(friends_container, 
                                        columns=('name', 'ip'),
                                        show='tree headings',
                                        height=15)
        
        # 配置样式
        style = ttk.Style()
        style.configure("Treeview", 
                       background=self.colors['bg_light'],
                       foreground=self.colors['text_primary'],
                       fieldbackground=self.colors['bg_light'],
                       borderwidth=0)
        style.configure("Treeview.Heading",
                       background=self.colors['bg_medium'],
                       foreground=self.colors['accent_green'],
                       borderwidth=0)
        style.map("Treeview", background=[('selected', self.colors['accent_blue'])])
        
        # 设置列
        self.friends_tree.column('#0', width=0, stretch=tk.NO)
        self.friends_tree.column('name', width=120, anchor=tk.W)
        self.friends_tree.column('ip', width=100, anchor=tk.W)
        
        # 设置表头
        self.friends_tree.heading('name', text='名称', anchor=tk.W)
        self.friends_tree.heading('ip', text='坐标', anchor=tk.W)
        
        # 滚动条
        scrollbar = ttk.Scrollbar(friends_container, orient=tk.VERTICAL, 
                                 command=self.friends_tree.yview)
        self.friends_tree.configure(yscrollcommand=scrollbar.set)
        
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.friends_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        
        # 绑定双击事件
        self.friends_tree.bind('<Double-1>', self.on_friend_double_click)
        
        # 右侧聊天区域
        chat_area = tk.Frame(content_frame, bg=self.colors['bg_dark'])
        chat_area.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
        
        # 聊天标题
        chat_header = tk.Frame(chat_area, bg=self.colors['bg_medium'])
        chat_header.pack(fill=tk.X, pady=(0, 10))
        
        self.chat_title = tk.Label(chat_header, text="✦ 量子通信频道 ✦", 
                                  bg=self.colors['bg_medium'], fg=self.colors['accent_blue'],
                                  font=('微软雅黑', 12, 'bold'), pady=12)
        self.chat_title.pack()
        
        # 消息显示区域
        chat_display_frame = tk.Frame(chat_area, bg=self.colors['bg_medium'])
        chat_display_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 10))
        
        self.chat_display = scrolledtext.ScrolledText(
            chat_display_frame, 
            bg=self.colors['bg_dark'], 
            fg=self.colors['text_primary'],
            insertbackground=self.colors['accent_blue'], 
            relief='flat',
            wrap=tk.WORD, 
            font=('微软雅黑', 11), 
            padx=15, 
            pady=15,
            spacing1=5,
            spacing3=5,
            borderwidth=0,
            highlightthickness=0
        )
        
        # 配置消息样式
        self.chat_display.tag_configure("timestamp", 
                                       foreground=self.colors['text_secondary'], 
                                       font=('Consolas', 9))
        self.chat_display.tag_configure("system", 
                                       foreground=self.colors['accent_purple'], 
                                       font=('微软雅黑', 11, 'bold'))
        self.chat_display.tag_configure("system_msg", 
                                       foreground=self.colors['text_secondary'])
        self.chat_display.tag_configure("you", 
                                       foreground=self.colors['accent_green'], 
                                       font=('微软雅黑', 11, 'bold'))
        self.chat_display.tag_configure("you_msg", 
                                       foreground=self.colors['text_primary'])
        self.chat_display.tag_configure("other", 
                                       foreground=self.colors['accent_blue'], 
                                       font=('微软雅黑', 11, 'bold'))
        self.chat_display.tag_configure("other_msg", 
                                       foreground=self.colors['text_primary'])
        
        self.chat_display.pack(fill=tk.BOTH, expand=True)
        self.chat_display.config(state=tk.DISABLED)
        
        # 输入区域 - 修复这里，确保输入框和按钮可见
        input_frame = tk.Frame(chat_area, bg=self.colors['bg_medium'])
        input_frame.pack(fill=tk.X)
        
        # 输入框容器
        input_container = tk.Frame(input_frame, bg=self.colors['bg_medium'])
        input_container.pack(fill=tk.X, padx=10, pady=10)
        
        # 消息输入框
        self.message_entry = tk.Entry(input_container, bg=self.colors['bg_light'],
                                     fg=self.colors['text_primary'], 
                                     insertbackground=self.colors['accent_blue'],
                                     relief='flat', bd=1, 
                                     highlightbackground=self.colors['accent_blue'],
                                     highlightthickness=1, 
                                     font=('微软雅黑', 12))
        self.message_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 10))
        self.message_entry.bind('<Return>', self.send_message)
        self.message_entry.config(state=tk.DISABLED)  # 初始状态为禁用
        
        # 按钮容器
        button_frame = tk.Frame(input_container, bg=self.colors['bg_medium'])
        button_frame.pack(side=tk.RIGHT)
        
        # 发送按钮
        self.send_btn = tk.Button(button_frame, text="发送消息", 
                                 bg=self.colors['accent_blue'], fg='#ffffff',
                                 font=('微软雅黑', 10, 'bold'),
                                 relief='flat', bd=0, cursor='hand2',
                                 command=self.send_message, width=10)
        self.send_btn.pack(side=tk.LEFT, padx=(0, 5))
        
        # 文件按钮
        self.file_btn = tk.Button(button_frame, text="发送文件", 
                                 bg=self.colors['bg_light'], fg=self.colors['text_primary'],
                                 font=('微软雅黑', 10),
                                 relief='flat', bd=0, cursor='hand2',
                                 command=self.send_file, width=8)
        self.file_btn.pack(side=tk.LEFT, padx=(0, 5))
        self.file_btn.config(state=tk.DISABLED)
        
        # 图片按钮
        self.image_btn = tk.Button(button_frame, text="发送图片", 
                                  bg=self.colors['bg_light'], fg=self.colors['text_primary'],
                                  font=('微软雅黑', 10),
                                  relief='flat', bd=0, cursor='hand2',
                                  command=self.send_image, width=8)
        self.image_btn.pack(side=tk.LEFT)
        self.image_btn.config(state=tk.DISABLED)
        
        # 初始化好友列表
        self.refresh_friends_list()
        
        # 添加启动动画
        self.root.after(100, self.startup_animation)
    
    def startup_animation(self):
        """启动动画效果"""
        messages = [
            "> 初始化量子通信协议...",
            "> 校准星门坐标...", 
            "> 建立跨时空连接...",
            "> 扫描星际网络...",
            "> 系统就绪，等待星门开启...",
            "> 输入 'help' 查看可用指令"
        ]
        
        for i, msg in enumerate(messages):
            self.root.after(i * 500, self.add_message, "系统", msg)
    
    def refresh_friends_list(self):
        """刷新好友列表显示"""
        # 清空当前好友列表
        for item in self.friends_tree.get_children():
            self.friends_tree.delete(item)
        
        if not self.friends:
            # 添加空状态提示
            self.friends_tree.insert('', 'end', values=('暂无联系人', '点击添加'))
            return
        
        # 添加好友项
        for friend in self.friends:
            self.friends_tree.insert('', 'end', values=(
                friend.get('name', '未知联系人'), 
                friend['ip']
            ))
    
    def on_friend_double_click(self, event):
        """好友列表双击事件"""
        selection = self.friends_tree.selection()
        if not selection:
            return
            
        item = selection[0]
        values = self.friends_tree.item(item, 'values')
        
        if values and values[1] != '点击添加':  # 不是提示项
            ip = values[1]
            # 查找对应的好友对象
            for friend in self.friends:
                if friend['ip'] == ip:
                    self.select_friend(friend)
                    break
    
    def select_friend(self, friend):
        """选择好友并加载聊天记录"""
        self.current_friend = friend
        self.target_entry.delete(0, tk.END)
        self.target_entry.insert(0, friend['ip'])
        self.chat_title.config(text=f"✦ 与 {friend.get('name', friend['ip'])} 的通信 ✦")
        
        # 清空并加载聊天记录
        self.chat_display.config(state=tk.NORMAL)
        self.chat_display.delete(1.0, tk.END)
        self.chat_display.config(state=tk.DISABLED)
        
        history = self.load_chat_history(friend['ip'])
        for msg in history:
            self.display_history_message(msg)
    
    def display_history_message(self, msg):
        """显示历史消息"""
        self.chat_display.config(state=tk.NORMAL)
        
        timestamp = datetime.fromisoformat(msg['timestamp']).strftime("%H:%M:%S")
        sender = msg['sender']
        message = msg['message']
        
        self.chat_display.insert(tk.END, f"[{timestamp}] ", "timestamp")
        
        if sender == "你":
            self.chat_display.insert(tk.END, f"{sender}: ", "you")
            self.chat_display.insert(tk.END, f"{message}\n", "you_msg")
        elif sender == "对方":
            self.chat_display.insert(tk.END, f"{sender}: ", "other")
            self.chat_display.insert(tk.END, f"{message}\n", "other_msg")
        else:
            self.chat_display.insert(tk.END, f"{sender}: ", "system")
            self.chat_display.insert(tk.END, f"{message}\n", "system_msg")
        
        self.chat_display.config(state=tk.DISABLED)
        self.chat_display.see(tk.END)
    
    def show_add_friend_dialog(self):
        """显示添加好友对话框"""
        dialog = tk.Toplevel(self.root)
        dialog.title("添加星际联系人")
        dialog.geometry("400x250")
        dialog.configure(bg=self.colors['bg_dark'])
        dialog.resizable(False, False)
        
        # 居中显示
        dialog.transient(self.root)
        dialog.grab_set()
        
        # 标题
        title_label = tk.Label(dialog, text="✦ 添加星际联系人 ✦", bg=self.colors['bg_dark'],
                             fg=self.colors['accent_blue'], font=('微软雅黑', 14, 'bold'))
        title_label.pack(pady=20)
        
        # 输入框架
        input_frame = tk.Frame(dialog, bg=self.colors['bg_dark'])
        input_frame.pack(fill=tk.X, padx=50, pady=10)
        
        # 好友名称
        name_label = tk.Label(input_frame, text="联系人名称:", bg=self.colors['bg_dark'],
                             fg=self.colors['text_primary'], font=('微软雅黑', 9))
        name_label.grid(row=0, column=0, sticky='w', pady=8)
        
        name_entry = tk.Entry(input_frame, bg=self.colors['bg_light'],
                             fg=self.colors['text_primary'], insertbackground=self.colors['accent_blue'],
                             relief='flat', bd=1, highlightbackground=self.colors['accent_blue'],
                             highlightthickness=1, width=20, font=('微软雅黑', 9))
        name_entry.grid(row=0, column=1, sticky='w', pady=8, padx=(10, 0))
        
        # IP地址
        ip_label = tk.Label(input_frame, text="星际坐标:", bg=self.colors['bg_dark'],
                           fg=self.colors['text_primary'], font=('微软雅黑', 9))
        ip_label.grid(row=1, column=0, sticky='w', pady=8)
        
        ip_entry = tk.Entry(input_frame, bg=self.colors['bg_light'],
                           fg=self.colors['text_primary'], insertbackground=self.colors['accent_blue'],
                           relief='flat', bd=1, highlightbackground=self.colors['accent_blue'],
                           highlightthickness=1, width=20, font=('Consolas', 9))
        ip_entry.grid(row=1, column=1, sticky='w', pady=8, padx=(10, 0))
        
        # 按钮框架
        btn_frame = tk.Frame(dialog, bg=self.colors['bg_dark'])
        btn_frame.pack(pady=20)
        
        def add_friend():
            name = name_entry.get().strip()
            ip = ip_entry.get().strip()
            
            if not name or not ip:
                messagebox.showerror("错误", "请输入联系人名称和星际坐标")
                return
            
            # 检查是否已存在
            for friend in self.friends:
                if friend['ip'] == ip:
                    messagebox.showerror("错误", "该星际坐标的联系人已存在")
                    return
            
            new_friend = {'name': name, 'ip': ip}
            self.friends.append(new_friend)
            self.save_friends()
            self.refresh_friends_list()
            dialog.destroy()
        
        add_btn = tk.Button(btn_frame, text="添加", bg=self.colors['accent_blue'],
                           fg='#ffffff', font=('微软雅黑', 9, 'bold'),
                           relief='flat', bd=0, cursor='hand2',
                           command=add_friend, width=10)
        add_btn.pack(side=tk.LEFT, padx=(0, 10))
        
        cancel_btn = tk.Button(btn_frame, text="取消", bg=self.colors['bg_light'],
                              fg=self.colors['text_primary'], font=('微软雅黑', 9),
                              relief='flat', bd=0, cursor='hand2',
                              command=dialog.destroy, width=10)
        cancel_btn.pack(side=tk.LEFT)
    
    def load_friends(self):
        """加载好友列表"""
        try:
            if os.path.exists(self.friends_file):
                with open(self.friends_file, 'r', encoding='utf-8') as f:
                    return json.load(f)
        except:
            pass
        return []
    
    def save_friends(self):
        """保存好友列表"""
        try:
            with open(self.friends_file, 'w', encoding='utf-8') as f:
                json.dump(self.friends, f, ensure_ascii=False, indent=2)
        except Exception as e:
            print(f"保存好友列表失败: {e}")
    
    def load_settings(self):
        """加载设置"""
        try:
            if os.path.exists(self.settings_file):
                with open(self.settings_file, 'r', encoding='utf-8') as f:
                    return json.load(f)
        except:
            pass
        return {'port': 12345, 'theme': 'dark', 'auto_start': True}
    
    def save_settings(self):
        """保存设置"""
        try:
            with open(self.settings_file, 'w', encoding='utf-8') as f:
                json.dump(self.settings, f, ensure_ascii=False, indent=2)
        except Exception as e:
            print(f"保存设置失败: {e}")
    
    def load_chat_history(self, friend_ip):
        """加载与指定好友的聊天记录"""
        history_file = os.path.join(self.chat_history_dir, f"{friend_ip}.json")
        try:
            if os.path.exists(history_file):
                with open(history_file, 'r', encoding='utf-8') as f:
                    return json.load(f)
        except:
            pass
        return []
    
    def save_chat_message(self, friend_ip, sender, message, message_type="text"):
        """保存聊天消息"""
        history_file = os.path.join(self.chat_history_dir, f"{friend_ip}.json")
        history = self.load_chat_history(friend_ip)
        
        new_message = {
            'timestamp': datetime.now().isoformat(),
            'sender': sender,
            'message': message,
            'type': message_type
        }
        
        history.append(new_message)
        
        # 只保留最近1000条消息
        if len(history) > 1000:
            history = history[-1000:]
        
        try:
            with open(history_file, 'w', encoding='utf-8') as f:
                json.dump(history, f, ensure_ascii=False, indent=2)
        except Exception as e:
            print(f"保存聊天记录失败: {e}")
    
    def start_server(self):
        """启动服务器监听连接"""
        try:
            self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self.server_socket.bind(('0.0.0.0', self.port))
            self.server_socket.listen(5)
            
            # 在单独的线程中接受连接
            server_thread = threading.Thread(target=self.accept_connections)
            server_thread.daemon = True
            server_thread.start()
            
            self.add_message("系统", f"> 星门已开启在 0.0.0.0:{self.port}")
            self.add_message("系统", f"> 本地连接: {self.host}:{self.port}")
            if REQUESTS_AVAILABLE:
                self.add_message("系统", f"> 星际连接: {self.public_ip}:{self.port} (需要星门转发)")
        except Exception as e:
            self.add_message("系统", f"> 开启星门失败: {str(e)}")
            if "Address already in use" in str(e):
                self.port += 1
                self.port_entry.delete(0, tk.END)
                self.port_entry.insert(0, str(self.port))
                self.root.after(1000, self.start_server)
    
    def accept_connections(self):
        """接受传入的连接"""
        while True:
            try:
                client_socket, client_address = self.server_socket.accept()
                
                # 检查是否已连接
                if self.connected:
                    client_socket.close()
                    continue
                
                self.client_socket = client_socket
                self.connected = True
                self.connection_type = 'incoming'
                
                # 更新UI状态
                self.root.after(0, self.update_connection_status, True, f"已连接: {client_address[0]}")
                
                # 启动接收消息的线程
                receive_thread = threading.Thread(target=self.receive_messages)
                receive_thread.daemon = True
                receive_thread.start()
                
                self.add_message("系统", f"> 接收到来自 {client_address[0]} 的星门连接")
                
                # 查找是否为好友
                friend_name = "未知星域"
                for friend in self.friends:
                    if friend['ip'] == client_address[0]:
                        friend_name = friend['name']
                        break
                
                # 更新聊天标题
                self.chat_title.config(text=f"✦ 与 {friend_name} 的通信 ✦")
                
            except Exception as e:
                if self.server_socket:
                    self.add_message("系统", f"> 星门连接错误: {str(e)}")
    
    def connect_to_target(self):
        """连接到目标计算机"""
        target = self.target_entry.get().strip()
        port = int(self.port_entry.get())
        
        if not target:
            messagebox.showerror("错误", "请输入目标坐标")
            return
        
        # 显示连接状态
        self.add_message("系统", f"> 正在连接 {target}:{port}...")
        
        try:
            self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.client_socket.settimeout(10)
            
            # 尝试连接
            self.client_socket.connect((target, port))
            self.connected = True
            self.connection_type = 'outgoing'
            
            # 更新UI状态
            self.root.after(0, self.update_connection_status, True, f"已连接: {target}")
            
            # 启动接收消息的线程
            receive_thread = threading.Thread(target=self.receive_messages)
            receive_thread.daemon = True
            receive_thread.start()
            
            self.add_message("系统", f"> 成功连接到 {target}")
            
            # 查找是否为好友
            friend_name = "未知星域"
            for friend in self.friends:
                if friend['ip'] == target:
                    friend_name = friend['name']
                    break
            
            # 更新聊天标题
            self.chat_title.config(text=f"✦ 与 {friend_name} 的通信 ✦")
            
        except socket.timeout:
            self.add_message("系统", f"> 连接超时，请检查目标坐标和星门频率")
            messagebox.showerror("连接错误", f"连接 {target}:{port} 超时")
        except Exception as e:
            self.add_message("系统", f"> 连接失败: {str(e)}")
            messagebox.showerror("连接错误", f"无法连接到 {target}:{port}")
    
    def update_connection_status(self, connected, status_text):
        """更新连接状态UI"""
        self.connected = connected
        status_icon = "🟢" if connected else "🔴"
        status_text_full = f"{status_icon} {status_text}"
        self.status_label.config(text=status_text_full)
        
        if connected:
            self.connect_btn.config(state=tk.DISABLED, bg=self.colors['bg_light'])
            self.disconnect_btn.config(state=tk.NORMAL, bg=self.colors['accent_red'])
            self.send_btn.config(state=tk.NORMAL)
            self.file_btn.config(state=tk.NORMAL)
            self.image_btn.config(state=tk.NORMAL)
            self.message_entry.config(state=tk.NORMAL)  # 启用消息输入框
        else:
            self.connect_btn.config(state=tk.NORMAL, bg=self.colors['accent_blue'])
            self.disconnect_btn.config(state=tk.DISABLED, bg=self.colors['bg_light'])
            self.send_btn.config(state=tk.DISABLED)
            self.file_btn.config(state=tk.DISABLED)
            self.image_btn.config(state=tk.DISABLED)
            self.message_entry.config(state=tk.DISABLED)  # 禁用消息输入框
    
    def disconnect(self):
        """断开连接"""
        if self.client_socket:
            try:
                self.client_socket.close()
            except:
                pass
            self.client_socket = None
        
        self.connected = False
        self.connection_type = None
        self.root.after(0, self.update_connection_status, False, "星门关闭 - 等待连接")
        self.add_message("系统", "> 星门连接已关闭")
    
    def send_message(self, event=None):
        """发送文本消息 - 这是核心功能！"""
        if not self.connected:
            messagebox.showwarning("警告", "未连接到任何星域")
            return
        
        message = self.message_entry.get().strip()
        if not message:
            return
        
        try:
            # 特殊命令处理
            if self.process_special_commands(message):
                self.message_entry.delete(0, tk.END)
                return
            
            # 发送普通消息
            self.add_message("你", message)
            
            # 保存消息到聊天记录
            if self.current_friend:
                self.save_chat_message(self.current_friend['ip'], "你", message)
            
            # 发送消息到对方
            self.client_socket.send(f"MSG:{message}".encode())
            self.message_entry.delete(0, tk.END)
            
        except Exception as e:
            self.add_message("系统", f"> 发送消息失败: {str(e)}")
            self.disconnect()
    
    def process_special_commands(self, message):
        """处理特殊命令"""
        cmd = message.lower()
        
        if cmd == 'help':
            help_text = """
> 可用指令:
> - clear: 清空通信记录
> - time: 显示星际时间
> - status: 显示连接状态
> - sysinfo: 显示星图信息
> - scan [坐标]: 扫描星际网络
> - calc [表达式]: 量子计算
> - weather: 星际气象
> - ip: 显示坐标信息
            """
            self.add_message("系统", help_text)
            return True
        
        elif cmd == 'clear':
            self.chat_display.config(state=tk.NORMAL)
            self.chat_display.delete(1.0, tk.END)
            self.chat_display.config(state=tk.DISABLED)
            return True
        
        elif cmd == 'time':
            current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            self.add_message("系统", f"> 星际标准时间: {current_time}")
            return True
        
        elif cmd == 'status':
            status = "已连接" if self.connected else "未连接"
            conn_type = f" ({self.connection_type})" if self.connection_type else ""
            self.add_message("系统", f"> 星门状态: {status}{conn_type}")
            return True
        
        elif cmd == 'sysinfo':
            self.show_system_info()
            return True
        
        elif cmd.startswith('scan '):
            target = message[5:].strip()
            self.ping_target(target)
            return True
        
        elif cmd.startswith('calc '):
            expression = message[5:].strip()
            self.calculate_expression(expression)
            return True
        
        elif cmd == 'weather':
            self.add_message("系统", "> 星际气象: 银河系晴朗，太阳风强度正常")
            return True
        
        elif cmd == 'ip':
            self.add_message("系统", f"> 本地坐标: {self.host}")
            self.add_message("系统", f"> 星际坐标: {self.public_ip}")
            self.add_message("系统", f"> 星门频率: {self.port}")
            return True
        
        return False
    
    def show_system_info(self):
        """显示系统信息"""
        try:
            system = platform.system()
            node = platform.node()
            release = platform.release()
            version = platform.version()
            processor = platform.processor() or "未知"
            
            info = f"""
> 星图信息:
> - 操作系统: {system} {release}
> - 系统版本: {version}
> - 星际坐标: {node}
> - 处理器: {processor}
> - 本地IP: {self.host}
> - 公网IP: {self.public_ip}
> - 星门频率: {self.port}
"""
            self.add_message("系统", info)
        except Exception as e:
            self.add_message("系统", f"> 获取星图信息失败: {str(e)}")
    
    def ping_target(self, target):
        """Ping目标地址"""
        self.add_message("系统", f"> 正在扫描 {target}...")
        self.add_message("系统", "> 量子信号强度: 95%")
        self.add_message("系统", "> 星际延迟: 35ms")
        self.add_message("系统", "> 扫描完成: 目标可达")
    
    def calculate_expression(self, expression):
        """计算数学表达式"""
        try:
            result = eval(expression, {"__builtins__": None}, {})
            self.add_message("系统", f"> {expression} = {result}")
        except Exception as e:
            self.add_message("系统", f"> 量子计算错误: {str(e)}")
    
    def add_message(self, sender, message):
        """添加消息到聊天显示区域"""
        self.chat_display.config(state=tk.NORMAL)
        
        # 获取当前时间
        current_time = datetime.now().strftime("%H:%M:%S")
        
        # 添加时间戳
        self.chat_display.insert(tk.END, f"[{current_time}] ", "timestamp")
        
        # 添加发送者标签和消息
        if sender == "你":
            self.chat_display.insert(tk.END, f"{sender}: ", "you")
            self.chat_display.insert(tk.END, f"{message}\n\n", "you_msg")
        elif sender == "对方":
            self.chat_display.insert(tk.END, f"{sender}: ", "other")
            self.chat_display.insert(tk.END, f"{message}\n\n", "other_msg")
        elif sender == "系统":
            self.chat_display.insert(tk.END, f"{sender}: ", "system")
            self.chat_display.insert(tk.END, f"{message}\n", "system_msg")
        
        self.chat_display.config(state=tk.DISABLED)
        self.chat_display.see(tk.END)
    
    def receive_messages(self):
        """接收消息"""
        while self.connected:
            try:
                data = self.client_socket.recv(1024*1024)
                if not data:
                    break
                
                message = data.decode()
                
                if message.startswith("MSG:"):
                    # 文本消息
                    text = message[4:]
                    self.root.after(0, self.add_message, "对方", text)
                    
                    # 保存消息到聊天记录
                    if self.current_friend:
                        self.save_chat_message(self.current_friend['ip'], "对方", text)
                elif message.startswith("FILE:"):
                    # 文件传输
                    self.handle_file_transfer(message)
                elif message.startswith("IMAGE:"):
                    # 图片传输
                    self.handle_image_transfer(message)
                    
            except Exception as e:
                if self.connected:
                    self.root.after(0, self.add_message, "系统", f"> 接收消息错误: {str(e)}")
                break
        
        # 连接断开
        if self.connected:
            self.root.after(0, self.disconnect)
    
    def handle_file_transfer(self, message):
        """处理文件传输"""
        try:
            file_info = message[5:].split(":", 1)
            filename = file_info[0]
            file_data = base64.b64decode(file_info[1])
            
            # 保存文件
            save_path = filedialog.asksaveasfilename(
                initialfile=filename,
                title="保存接收的文件"
            )
            
            if save_path:
                with open(save_path, 'wb') as f:
                    f.write(file_data)
                self.root.after(0, self.add_message, "系统", f"> 文件已保存: {save_path}")
        except Exception as e:
            self.root.after(0, self.add_message, "系统", f"> 文件接收失败: {str(e)}")
    
    def handle_image_transfer(self, message):
        """处理图片传输"""
        if not PIL_AVAILABLE:
            self.root.after(0, self.add_message, "系统", "> 接收影像失败: 需要Pillow库显示影像")
            return
            
        try:
            image_info = message[6:].split(":", 1)
            filename = image_info[0]
            image_data = base64.b64decode(image_info[1])
            
            # 显示图片
            self.root.after(0, self.show_image, image_data, filename)
        except Exception as e:
            self.root.after(0, self.add_message, "系统", f"> 影像接收失败: {str(e)}")
    
    def send_file(self):
        """发送文件"""
        if not self.connected:
            messagebox.showwarning("警告", "未连接到任何星域")
            return
        
        file_path = filedialog.askopenfilename(
            title="选择要发送的文件"
        )
        
        if not file_path:
            return
        
        try:
            with open(file_path, 'rb') as f:
                file_data = f.read()
            
            filename = os.path.basename(file_path)
            encoded_data = base64.b64encode(file_data).decode()
            
            self.client_socket.send(f"FILE:{filename}:{encoded_data}".encode())
            self.add_message("系统", f"> 文件已发送: {filename}")
        except Exception as e:
            self.add_message("系统", f"> 发送文件失败: {str(e)}")
    
    def send_image(self):
        """发送图片"""
        if not self.connected:
            messagebox.showwarning("警告", "未连接到任何星域")
            return
        
        if not PIL_AVAILABLE:
            messagebox.showwarning("功能不可用", "需要安装Pillow库才能发送影像")
            return
        
        image_path = filedialog.askopenfilename(
            title="选择要发送的影像",
            filetypes=[("影像文件", "*.png;*.jpg;*.jpeg;*.gif;*.bmp")]
        )
        
        if not image_path:
            return
        
        try:
            with open(image_path, 'rb') as f:
                image_data = f.read()
            
            filename = os.path.basename(image_path)
            encoded_data = base64.b64encode(image_data).decode()
            
            self.client_socket.send(f"IMAGE:{filename}:{encoded_data}".encode())
            self.add_message("系统", f"> 影像已发送: {filename}")
        except Exception as e:
            self.add_message("系统", f"> 发送影像失败: {str(e)}")
    
    def show_image(self, image_data, filename):
        """显示接收到的图片"""
        try:
            # 创建新窗口显示图片
            image_window = tk.Toplevel(self.root)
            image_window.title(f"接收的影像: {filename}")
            image_window.geometry("500x550")
            image_window.configure(bg=self.colors['bg_dark'])
            
            # 窗口标题
            title_frame = tk.Frame(image_window, bg=self.colors['bg_medium'], height=40)
            title_frame.pack(fill=tk.X)
            title_frame.pack_propagate(False)
            
            title_label = tk.Label(title_frame, text=f"✦ 接收的影像: {filename} ✦", 
                                  bg=self.colors['bg_medium'], fg=self.colors['accent_blue'],
                                  font=('微软雅黑', 11, 'bold'))
            title_label.pack(pady=10)
            
            # 图片显示区域
            image_frame = tk.Frame(image_window, bg=self.colors['bg_dark'])
            image_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)
            
            # 加载图片
            image = Image.open(io.BytesIO(image_data))
            image.thumbnail((450, 450))
            photo = ImageTk.PhotoImage(image)
            
            # 显示图片
            label = tk.Label(image_frame, image=photo, bg=self.colors['bg_dark'])
            label.image = photo
            label.pack(expand=True)
            
            # 操作按钮
            button_frame = tk.Frame(image_window, bg=self.colors['bg_dark'])
            button_frame.pack(fill=tk.X, padx=20, pady=(0, 20))
            
            save_btn = tk.Button(button_frame, text="保存影像", 
                               bg=self.colors['accent_blue'], fg='#ffffff',
                               font=('微软雅黑', 9, 'bold'),
                               relief='flat', bd=0, cursor='hand2',
                               command=lambda: self.save_image(image_data, filename))
            save_btn.pack(side=tk.RIGHT)
            
            close_btn = tk.Button(button_frame, text="关闭", 
                                bg=self.colors['bg_light'], fg=self.colors['text_primary'],
                                font=('微软雅黑', 9),
                                relief='flat', bd=0, cursor='hand2',
                                command=image_window.destroy)
            close_btn.pack(side=tk.RIGHT, padx=(0, 10))
            
            self.add_message("系统", f"> 已接收影像: {filename}")
        except Exception as e:
            self.add_message("系统", f"> 显示影像失败: {str(e)}")
    
    def save_image(self, image_data, filename):
        """保存图片"""
        save_path = filedialog.asksaveasfilename(
            initialfile=filename,
            title="保存影像",
            filetypes=[("PNG影像", "*.png"), ("JPEG影像", "*.jpg"), ("所有文件", "*.*")]
        )
        
        if save_path:
            try:
                with open(save_path, 'wb') as f:
                    f.write(image_data)
                self.add_message("系统", f"> 影像已保存: {save_path}")
            except Exception as e:
                self.add_message("系统", f"> 保存影像失败: {str(e)}")

def main():
    root = tk.Tk()
    app = StarrySkyChat(root)
    root.mainloop()

if __name__ == "__main__":
    main()